約 3,791,470 件
https://w.atwiki.jp/intensity/pages/13.html
動作マザーボード Intel系M/B XP32bit XP64bit Vista32bit Vista64bit 732bit 764bit 備考 abit Fatal1ty F-I90HD - - - - - - ASUSTek P8Z77-V PRO - - - - - ○ ASUSTek P7P55D-E EVO - - - - - ○ ASUSTek P7P55D-E - - - - - ○ ASUSTek P6T ○ × ○ ○ - ○ X58チップセット非対応 ASUSTek P6T DeluxeV2 ○ - - ○ - - ASUSTek P6T Deluxe ○ - - ○ - - 最下段とその一つ上のPCI-Ex16形状スロットで確認 ASUSTek SABERTOOTH X58 - - - - - ○ 最上段のPCIe x1で確認 ASUSTek Rampage Extreme - - - ○ - - ASUSTek P5Q-Deluxe ○ - - - - ○ ASUSTek P5Q-E ○ - - - - - ASUSTek P5B-Deluxe ○ - - - - - ASUSTek P5K ○ - - - - - ASUSTek P5K-PRO - - - - - - ASUSTek P5K-E ○ ○ - - ○ - Biostar TPower I45 ○ - - - - - 下側のPCIe x1で確認 EVGA P55 FTW - - - - - ○ 上段のPCIe x1で確認 EVGA X58 SLI Micro - - - - - ○ 下段のPCIe x1で確認 EVGA X58 E760 - - - - - ○ 下から2段目のスロットで確認 Gigabyte GA-8I945G PRO - - - - - - Gigabyte GA-945G-DS3 - - - - - - Gigabyte GA-965P-DS3P - - ○ - - ○ Gigabyte GA-EP35-DS3R ○ ○ ○ ○ - - Gigabyte GA-EP35-DS4 - - ○ - ○ - PCI-Ex16形状スロットで確認 Gigabyte GA-EP45-UD3R ○ - ○ - - ○ Gigabyte GA-EX58-DS4 - - ○ - - - Gigabyte GA-EX58-EXTREME - - - - - ○ 最下段のPCI-Ex8形状スロットで確認 Gigabyte GA-EX58-UD3R ○ - ○ - - - Gigabyte GA-G33M-DS2R ○ - - - - - Gigabyte GA-P35-DS3 - - - - - ○ 最上段のPCI-Ex1で確認 Gigabyte GA-P35-DS3R ○ ○ - - - - Gigabyte GA-P35-DS4 ○ - - ○ - - Gigabyte GA-P55-DS4 ○ - ○ - - - Gigabyte GA-P55A-UD3R - - ○ - - ○ 最上段のPCI-Ex1形状スロットで確認 Gigabyte GA-Z68X-UD5-B3 (rev. 1.0) - - - - - ○ 最上段のPCI-Ex1形状スロットで確認(win2k8R2でも動作確認) Intel DG33TL ○ - - - - - Intel DG45ID ○ - - - - - Intel DP35DPM ○ - - - - - Intel DP965LT ○ - - - - - MSI P45 Neo-F - - ○ - - - MSI X58 Platinum - - - - - ○ 最上段と最下段のPCI-Ex1形状スロットで確認 AMD系M/B XP32bit XP64bit Vista32bit Vista64bit 732bit 764bit 備考 ASUSTek A8S-X ○ - - - - - 認識しない人もいた様子 ASUSTek Crosshair IV Formula - - - - - ○ 3段目x16スロットで確認 ASUSTek M2A-VM HDMI ○ - - - - - ASUSTek M2N-E ○ - - - - - ASUSTek M3A ○ - - - - - ASUSTek M4N78-Pro △ - - △ - - x1スロットでは認識しない、x16は一基しかないため実質使えないようなもの ASUSTek M4N82-Deluxe ○ - - ○ - - x1スロで動くかどうかは未確認 BIOSTAR TA790GXE - - - - - ○ x1スロ両方で動作確認。x16は未確認 DFI LanParty nF4 Sli-DR Expert - - - - - - FOXCONN A7GM-S ○ - ○ - ○ ○ うちだけかもしれないけどオンボードサウンドを無効にしないと認識しない Gigabyte GA-890FXA-UD5 - - - - - ○ 4段目x16_2スロット、5段目x4スロット、6段目x8スロットで確認 Jetway HA06 ○ - - - - ○ 最下段スロx16形状で動作(上段はグラボ使用)、x1は未確認 MSI K9A2-Platinum ○ - - - - - 3段目x16スロットで確認、x1スロットでの動作は未確認 非動作マザーボード M/B 症状 ASUSTek A8S-X 認識しない X58チップセットマザー? 認識しない可能性 HDMI 某DVI切替機でごにょごにょ前提。 ゲーム機 PlayStation 3 ○ (常にごにょごにょ必須) Xbox360 ○ (ダッシュボードとゲーム画面はごにょごにょしなくてもキャプチャ可能) 新型Xbox360 ○ (ダッシュボードとゲーム画面はごにょごにょしなくてもキャプチャ可能) ユニデンチューナー DT100-HDMI × DT300 × 東芝レコーダー RD-A600 ○ RD-S600 ○ RD-S300 ○ RD-E300 ○ RD-XD92D ○ RD-X6 映像○ 音声×(ソフトウエアバージョンを最新にすれば○) RD-T1 映像○ 音声×(ソフトウエアバージョンを最新にすれば○) RD-Z1 ○ RD-E301 ○(2008/01/05購入、予想通りRD-E300と変わりは無かった) RD-A301 ○ パナソニックレコーダー DMR-BW200 映像○ 音声△ DMR-XW51 映像○ 音声△ DMR-XW31 映像○ 音声△ DMR-XW30 映像○ 音声△ ※パナ機のHDMI音声はBitStream出力する設定にしても、IntensityをBitStream非対応と判断して、 PCM出力に制限される。BitStreamをそのまま録音するには、Bit-Accurate対応の 光入力があるサウンドカードを増設して、光ケーブル経由で録音する必要がある。 (Creative Sound Blaster Digital Music PXが安くておすすめ) シャープレコーダー DV-ACW38 ○ DV-ARW22 ○ DV-ARW15 ○ アナログHDTVキャプチャに解説あり。 コンポーネント 大抵の機器は設定さえ正しければキャプできるので省略。
https://w.atwiki.jp/pv-3/
HDTVアナログキャプチャー機器とHDTV関連の気になるモノのまとめサイト 「PV3の私的まとめ」のミラーになります 整理をしながらの為、こちらの更新は当分の間遅くなります。 PS3-S201A PS3-S201A PS3-S201←第3次予約受付開始(8月下旬入荷予定との事) PS3-S201←第3次予約受付開始(8月下旬入荷予定との事) PS3-S201A←8月下旬予定 PS3-S201A←8月下旬予定 各キャプボの比較 PV4 利点: PV3よりも安い! D1~D4キャプチャ可能 光オーディオ端子も装備2統系 PCIなので古いマシンでも動かせる 拡張ツールがそのまま使える(はず) 欠点: また、購入競争になりそう・・・ ソフトウェアエンコードなのでPCへの負荷がでかい アナログキャプしかできない WindowsVista非対応(対応予定無し!) PCIなので帯域が必要 独自コーデックで独自コンテナ PV3 利点: 安い! D1~D4キャプチャ可能 光オーディオ端子も装備2統系 PCIなので古いマシンでも動かせる 拡張ツールが沢山 欠点: 安かったが販売終了らしい ソフトウェアエンコードなのでPCへの負荷がでかい アナログキャプしかできない WindowsVista非対応(対応予定無し!) PCIなので帯域が必要 独自コーデックで独自コンテナ Intensity pro 利点: HDMIキャプ可能 WindowsVista対応 PCI-Expressなので帯域の心配なし GameSwitchを使えば・・・ 欠点: やや高い ソフトウェアエンコードなのでPCへの負荷がでかい コンポーネント使用時に白飛びが起こる 海外メーカー PCI-Express非搭載PCには付けられない ソフトが面倒 HDRECS 利点: ハードウェアエンコードなので録画も軽い アナログRGB入力も可能でPC画面キャプチャもできる WindowsVista対応(64は不明) HDMIキャプ可能 PCI-Expressなので帯域の心配なし D4キャプ可能 S端子もOK GameSwitchを使えば・・・ 欠点: 高い! それぞれ1統系しかない? PCI-Express非搭載PCには付けられない 光オーディオ入力が無い(D4時不便) 独自コーデックでAVIコンテナ Monster X 利点: PCI-Expressなので帯域の心配なし WindowsVista対応(64は不明) 光オーディオ端子も装備 アナログ2ch入力もある(?) 意外と安い 欠点: PCI-Express非搭載PCには付けられない 入力1統系しかない(?) ソフトウェアエンコードなのでPCへの負荷がでかい アナログキャプしかできない Intensity Intensity Pro HDRECS PV3 Monster X PV4 メーカー Blackmagic Design ← カノープス アースソフト エスケイネット アースソフト 値段(実売税込) 3万5千円強 5万円弱 10万円弱 (新品入手不可) \31,290 18,800円(税別) コンポーネント/D端子入力 × コンポネ コンポネ D(2系統) D(1系統) D(2系統) HDMI入力 ○ ○ ○ × × × アナログRGB入力 × × ○ × × × 音声入力 HDMI HDMI, アナログ HDMI, アナログ 光デジタル(2系統) 光デジタル,アナログ 光デジタル(2系統) プレビュー(スルー)出力 HDMI HDMI, アナログ × × × × 対応解像度 480i1080i720p(480pには対応しないので注意) ← 480i480p1080i720p他多彩 480i480p1080i720p1080p(横960ピクセル) 480i480p1080i(720pは不明) 480i480p1080i720p スロット PCIe x1 ← PCIe x1 PCI 32bit/33MHz(PCI2.1) PCIe x1 PCI 32bit/33MHz(PCI2.2) エンコード方式 SW ← HW SW SW SW 対応OS 2000XP(64bit可)Server2003(64bit可)VistaMacOS X ← 2000XPVista 2000XP XPVista(Vista64は対応予定) 2000XP 添付ソフト 簡単なキャプチャソフト(ドライバパッケージに同梱) ← 各種 予約録画ソフト(ドライバパッケージに同梱) 録画ソフト(信号を検知して録画を開始する機能追加予定) 予約録画ソフト(ドライバパッケージに同梱) DirectShow 対応 ○(YUV422) ← × × ? × 録画方法 DirectShow 対応キャプチャソフト ← 添付ソフト ドライバパッケージに同梱のソフト 添付ソフト ドライバパッケージに同梱のソフト 録画ファイルフォーマット 任意 ← AVI 独自仕様は公開 AVI 独自仕様は公開 録画ファイルCodec(映像) 任意 ← Canopus HQ DV風の独自Codec仕様は公開 MotionJPEG DV風の独自Codec仕様は公開 エンコード方式 SW ← HW SW SW SW ロスレスキャプチャ ○ ← ×? × ×(?) × 各種長所 HDMIキャプチャとしては最安? HDMIもアナログも(一応)OK 多彩な入力端子/フォーマット録画が軽い(HWエンコ) 社長がスレ見てるという噂ユーザー作成のツールが豊富 PV3の代わりとして安価 社長がスレ見てるという噂ユーザー作成のツールが豊富 各種短所 海外メーカー製ソフトが面倒録画が重い(ドライバがこなれてない?) 海外メーカー製ソフトが面倒録画が重い(ドライバがこなれてない?)コンポネ使用時に白飛び(抵抗をカマせば対策できないことも無い) 高いCGMS-Aに反応することを明言 新品入手不可ドライバアップデートも無い? CGMS-Aに反応するかが不明 細かい仕様は出ていないのでPV3と同等とみなして書いてます
https://w.atwiki.jp/bmd_intensity/pages/29.html
HDMI 某DVI切替機でごにょごにょ前提。 ゲーム機 PlayStation 3 ○ (常にごにょごにょ必須) Xbox360 Elite ○ (ダッシュボードとゲーム画面はごにょごにょしなくてもキャプチャ可能) ユニデンチューナー DT100-HDMI × DT300 × 東芝レコーダー RD-A600 ○ RD-S600 ○ RD-S300 ○ RD-E300 ○ RD-XD92D ○ RD-X6 映像○ 音声×(ソフトウエアバージョンを最新にすれば○) RD-T1 映像○ 音声×(ソフトウエアバージョンを最新にすれば○) RD-Z1 ○ RD-E301 ○(2008/01/05購入、予想通りRD-E300と変わりは無かった) RD-A301 ○ パナソニックレコーダー DMR-BW200 映像○ 音声△ DMR-XW51 映像○ 音声△ DMR-XW31 映像○ 音声△ DMR-XW30 映像○ 音声△ ※パナ機のHDMI音声はBitStream出力する設定にしても、IntensityをBitStream非対応と判断して、 PCM出力に制限される。BitStreamをそのまま録音するには、Bit-Accurate対応の 光入力があるサウンドカードを増設して、光ケーブル経由で録音する必要がある。 (Creative Sound Blaster Digital Music PXが安くておすすめ) シャープレコーダー DV-ACW38 ○ DV-ARW22 ○ DV-ARW15 ○ アナログHDTVキャプチャに解説あり。 コンポーネント 大抵の機器は設定さえ正しければキャプできるので省略。
https://w.atwiki.jp/intense/
IntensE 04/22更新 「オフ会する・・・かも?」 更新 (04/22) MembeR=新メンバー追加、メンバーのプロフィール追加 MenU=Mamble追加、mina様blog追加、SOW存続活動(装甲騎兵師団)HP追加 IntensE HPへようこそ IntensEはS.O.Wで活動するクランです。 since:2008/06/25 member :46名 ranking:9位 ☚UP!!! クラン戦績:993戦/363勝/630敗(36%) ワオ!でもいいじゃまいか(ノ▽`*)たはー 当HPでは相互リンクをお願いしております!! 掲示板に書きこみをしていただくか、IntensE所属aikoまでお願いします。 CM募集㊥!!IntensE規約 強くなくてもおk 升の使用はどんな理由があろうと絶対禁止 誹謗中傷は一切禁止 空気読もう 最低限のマナーは守ってください 個人の行動は規制しませんが節度を持って行動してください 通報があれば、(証拠がある前提で)即座に追放致します 楽しむことが第一です!!! 加入される方は「MILED」、「.com」またはIntensEメンバーへ耳打ちか、募集部屋『負けたらクラン入れ!』(主に.com主催部屋)へ。 お知らせ ①~CW予定~ コムさんより伝言 「クラン戦についてですが、人数が集まり、したい!ってことになれば勝手にやってOKー」 とのことです^^ ②IRC導入について MenUのChocoAを参照にIRC導入をできるだけお願いします。 ③~自己紹介~ メンバーをクリックするとプロフィール的な?ものをみれるようにしました。 詳細はBBSを見てください。 ④~BBS~ ツリーBBSちょっと見にくいので・・・新BBS作成しました。 新しい話題はそちらへお願いします。 画像変更しました。 MenU
https://w.atwiki.jp/stockphoto_n/pages/32.html
白飛び、黒潰れしている写真はNGです。 メインの被写体出ない部分が多少白飛び、黒潰れしている分には問題ありません。 編集でカバーできる事も多いですが、撮影時にしっかりと露出を調整して 無意味な白飛び、黒潰れが発生しないようにしましょう。 例1 …白飛び。右上の雲の部分が真っ白になってしまっています。 例2 …黒潰れ。右側の岩山部分が真っ黒になってしまっています。
https://w.atwiki.jp/intensity/pages/22.html
//------------------------------------------------------------------------------------ // $Id Utils.cpp,v 1.10 2006/04/11 01 13 06 ivanr Exp $ // // Desc DirectShow utility class implementation // // Copyright (c) Blackmagic Design 2005. All rights reserved. //------------------------------------------------------------------------------------ #include "stdafx.h" #include "Utils.h" //----------------------------------------------------------------------------- // CDSUtils - Directshow utility class //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // AddFilter // Attempts to locate a filter of a given class ID and nameand add it to the graph HRESULT CDSUtils AddFilter(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { *ppFilter = NULL; IBaseFilter* pFilter = NULL; hr = CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { hr = pGraph- AddFilter(pFilter, pName); if (SUCCEEDED(hr)) { *ppFilter = pFilter; } else { SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddFilter2 // Attempts to locate a filter of a given class category and name HRESULT CDSUtils AddFilter2(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) { HRESULT hr = S_OK; if (pGraph pName ppFilter) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(clsid, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { if (0 == wcscmp(varName.bstrVal, pName)) { hr = pMoniker- BindToObject(NULL, NULL, IID_IBaseFilter, reinterpret_cast void** (ppFilter)); Loop = false; } } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } // if a filter has been located add it to the graph if (*ppFilter) { hr = pGraph- AddFilter(reinterpret_cast IBaseFilter* (*ppFilter), pName); } else { hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //------------------------------------------------------------------------------------------------- // GetUnconnectedPin // Attemptes to locate an unconnected pin on filter HRESULT CDSUtils GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter ppPin) { CComPtr IEnumPins pEnum = NULL; IPin* pPin = NULL; hr = pFilter- EnumPins( pEnum); if (SUCCEEDED(hr)) { while (pEnum- Next(1, pPin, NULL) == S_OK) { PIN_DIRECTION ThisPinDir; pPin- QueryDirection( ThisPinDir); if (ThisPinDir == PinDir) { IPin* pPinTemp = NULL; hr = pPin- ConnectedTo( pPinTemp); if (SUCCEEDED(hr)) { SAFE_RELEASE(pPinTemp); } else { // unconnected, return this pin *ppPin = pPin; hr = S_OK; break; } } SAFE_RELEASE(pPin); } } if (NULL == *ppPin) { // failed to find an unconnected pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified name on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pName ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { PIN_INFO info = {0}; hr = pIPin- QueryPinInfo( info); if (SUCCEEDED(hr)) { SAFE_RELEASE(info.pFilter); if (0 == wcsncmp(info.achName, pName, wcslen(pName))) { // matched the pin category *ppPin = pIPin; break; } } SAFE_RELEASE(pIPin); } } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // GetPin // Find the pin of the specified format type on the given filter // This method leaves an outstanding reference on the pin if successful HRESULT CDSUtils GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin) { HRESULT hr = S_OK; if (pFilter pFormat ppPin) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { // find the pin with the specified format IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { // match the pin direction PIN_DIRECTION pinDir; pIPin- QueryDirection( pinDir); if (pinDir == PinDir) { // match pin direction check the first media type returned from the upstream pin CComPtr IEnumMediaTypes pIEnumMT = NULL; hr = pIPin- EnumMediaTypes( pIEnumMT); if (SUCCEEDED(hr)) { AM_MEDIA_TYPE* pmt = NULL; hr = pIEnumMT- Next(1, pmt, NULL); if (S_OK == hr) { if (pmt- majortype == *pFormat) { // found the pin with the specified format *ppPin = pIPin; DeleteMediaType(pmt); break; } else { DeleteMediaType(pmt); } } } } SAFE_RELEASE(pIPin); } if (NULL == *ppPin) { // failed to find the named pin hr = E_FAIL; } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFiltersNamedPin // Connects two filters using the pin names, if no name is supplied the first // unconnected pin is used HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName) { HRESULT hr = S_OK; if (pUpstream pDownstream) { // get the upstream output pin CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; if (pDownstreamPinName) { hr = GetPin(pDownstream, pDownstreamPinName, pIPinInput); } else { hr = GetUnconnectedPin(pDownstream, PINDIR_INPUT, pIPinInput); } if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // ConnectFilters // Connects two filters by finding a pin on the upstream filter with the specified // major format type, e.g. For connecting an audio pin to a downstream filter HRESULT CDSUtils ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat) { HRESULT hr = S_OK; if (pUpstream pDownstream pFormat) { // find the upstream output pin with the specified format CComPtr IPin pIPinOutput = NULL; hr = GetPin(pUpstream, pFormat, PINDIR_OUTPUT, pIPinOutput); if (SUCCEEDED(hr)) { // get the downstream input pin CComPtr IPin pIPinInput = NULL; hr = GetPin(pDownstream, pFormat, PINDIR_INPUT, pIPinInput); if (SUCCEEDED(hr)) { // connect the pins hr = pGraph- Connect(pIPinOutput, pIPinInput); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RenderFilter // Renders the named output pin of the filter, or the first unconnected output if // no name is provided HRESULT CDSUtils RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName) { HRESULT hr = S_OK; if (pUpstream) { CComPtr IPin pIPinOutput = NULL; if (pUpstreamPinName) { hr = GetPin(pUpstream, pUpstreamPinName, pIPinOutput); } else { hr = GetUnconnectedPin(pUpstream, PINDIR_OUTPUT, pIPinOutput); } if (SUCCEEDED(hr)) { hr = pGraph- Render(pIPinOutput); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DisconnectAllPins // Disconnect all the pins of the filters in a graph HRESULT CDSUtils DisconnectAllPins(IGraphBuilder* pGraph) { HRESULT hr = S_OK; if (pGraph) { CComPtr IEnumFilters pIEnumFilters = NULL; hr = pGraph- EnumFilters( pIEnumFilters); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pIEnumFilters- Next(1, pFilter, NULL)) { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { IPin* pIPin = NULL; while (S_OK == pIEnumPins- Next(1, pIPin, NULL)) { IPin* pIPinConnection = NULL; if (S_OK == pIPin- ConnectedTo( pIPinConnection)) { // pins are connected, to disconnect filters, both pins must be disconnected hr = pGraph- Disconnect(pIPin); hr = pGraph- Disconnect(pIPinConnection); SAFE_RELEASE(pIPinConnection); } SAFE_RELEASE(pIPin); } } SAFE_RELEASE(pFilter); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindFilterInterface // Attempt to locate the specified interface HRESULT CDSUtils FindFilterInterface(IBaseFilter* pFilter, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { hr = pFilter- QueryInterface(riid, ppvInterface); } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the named pin or on the first pin if no // name is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pName) { hr = GetPin(pFilter, pName, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // FindPinInterface // Attempt to locate the interface on the pin with the specified format or on the first pin if no // format is provided. HRESULT CDSUtils FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID riid, void** ppvInterface) { HRESULT hr = S_OK; if (pFilter ppvInterface) { CComPtr IPin pIPin = NULL; if (pFormat) { hr = GetPin(pFilter, pFormat, PinDir, pIPin); } else { CComPtr IEnumPins pIEnumPins = NULL; hr = pFilter- EnumPins( pIEnumPins); if (SUCCEEDED(hr)) { hr = pIEnumPins- Next(1, pIPin, NULL); } } if (SUCCEEDED(hr)) { hr = pIPin- QueryInterface(riid, ppvInterface); } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // AddGraphToRot // Adds a DirectShow filter graph to the Running Object Table, // allowing GraphEdit to "spy" on a remote filter graph. HRESULT CDSUtils AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister) { HRESULT hr = S_OK; if (pUnkGraph pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; hr = GetRunningObjectTable(0, pROT); if (SUCCEEDED(hr)) { WCHAR wsz[128]; StringCchPrintfW(wsz, 128, L"FilterGraph %08x pid %08x\0", (DWORD_PTR)pUnkGraph, GetCurrentProcessId()); CComPtr IMoniker pMoniker = NULL; hr = CreateItemMoniker(L"!", wsz, pMoniker); if(SUCCEEDED(hr)) { // Use the ROTFLAGS_REGISTRATIONKEEPSALIVE to ensure a strong reference // to the object. Using this flag will cause the object to remain // registered until it is explicitly revoked with the Revoke() method. // // Not using this flag means that if GraphEdit remotely connects // to this graph and then GraphEdit exits, this object registration // will be deleted, causing future attempts by GraphEdit to fail until // this application is restarted or until the graph is registered again. hr = pROT- Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph, pMoniker, pdwRegister); } } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // RemoveGraphFromRot // Removes a filter graph from the Running Object Table void CDSUtils RemoveGraphFromRot(DWORD pdwRegister) { CComPtr IRunningObjectTable pROT = NULL; if (SUCCEEDED(GetRunningObjectTable(0, pROT))) { pROT- Revoke(pdwRegister); } } //------------------------------------------------------------------------------------ // CRegUtils - Registry utility class //------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------ // Constructor // CRegUtils CRegUtils() m_hKey(NULL) { } //------------------------------------------------------------------------------------ // Destructor // CRegUtils ~CRegUtils() { Close(); } //------------------------------------------------------------------------------------ // Open // Opens the specified subkey LONG CRegUtils Open(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegOpenKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, KEY_ALL_ACCESS, m_hKey); } //------------------------------------------------------------------------------------ // Create // Creates the specified subkey LONG CRegUtils Create(LPCTSTR lpSubKey) { Close(); m_subKeyName = "Software\\Blackmagic Design\\Samples\\"; m_subKeyName += lpSubKey; return RegCreateKeyEx(HKEY_LOCAL_MACHINE, m_subKeyName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, m_hKey, NULL); } //------------------------------------------------------------------------------------ // Close // Closes the subkey void CRegUtils Close() { RegCloseKey(m_hKey); m_hKey = NULL; m_subKeyName.empty(); } //------------------------------------------------------------------------------------ // SetString // Set the key for the named value of type string LONG CRegUtils SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_SZ, lpData, cbData); } //------------------------------------------------------------------------------------ // GetString // Query the key for the named value of type string LONG CRegUtils GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_SZ != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetBinary // Set the key for the named value of type binary LONG CRegUtils SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_BINARY, lpData, cbData); } //------------------------------------------------------------------------------------ // GetBinary // Query the key for the named value of type binary LONG CRegUtils GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_BINARY != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // SetDword // Set the key for the named value of type DWORD LONG CRegUtils SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) { return RegSetValueEx(m_hKey, valueName, 0, REG_DWORD, lpData, cbData); } //------------------------------------------------------------------------------------ // GetDword // Query the key for the named value of type DWORD LONG CRegUtils GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) { LONG ret = ERROR_SUCCESS; DWORD size = cbData, type = 0; ret = RegQueryValueEx(m_hKey, valueName, NULL, type, lpData, size); if ((size != cbData) || (REG_DWORD != type)) { ret = ERROR_INVALID_PARAMETER; } return ret; } //------------------------------------------------------------------------------------ // CUtils - utility class //------------------------------------------------------------------------------------ //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const AM_MEDIA_TYPE* pamt) { BITMAPINFOHEADER* pbmih = NULL; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); pbmih = pvih- bmiHeader; } } return pbmih; } //----------------------------------------------------------------------------- // GetBMIHeader // Returns the BITMAPINFOHEADER structure from media type format extension BITMAPINFOHEADER* CUtils GetBMIHeader(const CMediaType mt) { BITMAPINFOHEADER* pbmih = NULL; if (FORMAT_VideoInfo == mt.formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = mt.cbFormat); pbmih = pvih- bmiHeader; } else if (FORMAT_VideoInfo2 == mt.formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (mt.pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = mt.cbFormat); pbmih = pvih- bmiHeader; } return pbmih; } //----------------------------------------------------------------------------- // GetAvgTimePerFrame // Returns the average time per frame from media type format extension REFERENCE_TIME CUtils GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt) { REFERENCE_TIME rtAvgTimePerFrame = 0; if (pamt) { if (FORMAT_VideoInfo == pamt- formattype) { VIDEOINFOHEADER* pvih = reinterpret_cast VIDEOINFOHEADER* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } else if (FORMAT_VideoInfo2 == pamt- formattype) { VIDEOINFOHEADER2* pvih = reinterpret_cast VIDEOINFOHEADER2* (pamt- pbFormat); ASSERT(sizeof(VIDEOINFOHEADER2) = pamt- cbFormat); rtAvgTimePerFrame = pvih- AvgTimePerFrame; } } return rtAvgTimePerFrame; } //------------------------------------------------------------------------------------ // GetImageSize // Calculates the image size unsigned long CUtils GetImageSize(BITMAPINFOHEADER* pbmih) { unsigned long dwImageSize = 0; if (pbmih) { switch (pbmih- biCompression) { default case BI_RGB dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * pbmih- biBitCount) 3; break; case YVYU case 2YUY dwImageSize = (pbmih- biWidth * abs(pbmih- biHeight) * 16) 3; break; } } return dwImageSize; }
https://w.atwiki.jp/intensity/pages/21.html
//------------------------------------------------------------------------------------ // $Id Utils.h,v 1.6 2006/03/21 07 00 57 ivanr Exp $ // // Desc DirectShow utility class header // // Copyright (c) Blackmagic Design 2005. All rights reserved. //------------------------------------------------------------------------------------ #pragma once #include string #include dvdmedia.h //------------------------------------------------------------------------------------ // CDSUtils - Directshow utility class //------------------------------------------------------------------------------------ class CDSUtils { public static HRESULT AddFilter(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter); static HRESULT AddFilter2(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter); static HRESULT GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin); static HRESULT GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin); static HRESULT GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin); static HRESULT ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName); static HRESULT ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat); static HRESULT RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName); static HRESULT DisconnectAllPins(IGraphBuilder* pGraph); static HRESULT FindFilterInterface(IBaseFilter* pFilter, const IID riid, void** ppvInterface); static HRESULT FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID riid, void** ppvInterface); static HRESULT FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID riid, void** ppvInterface); static HRESULT AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister); static void RemoveGraphFromRot(DWORD pdwRegister); }; //------------------------------------------------------------------------------------ // CRegUtils - Registry utility class //------------------------------------------------------------------------------------ class CRegUtils { public CRegUtils(); ~CRegUtils(); LONG Open(LPCTSTR lpSubKey); LONG Create(LPCTSTR lpSubKey); void Close(); LONG SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData); LONG GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData); LONG SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData); LONG GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData); LONG SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData); LONG GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData); private std string m_subKeyName; HKEY m_hKey; }; //------------------------------------------------------------------------------------ // CUtils - utility class //------------------------------------------------------------------------------------ class CUtils { public static BITMAPINFOHEADER* GetBMIHeader(const AM_MEDIA_TYPE* pamt); static BITMAPINFOHEADER* GetBMIHeader(const CMediaType mt); static REFERENCE_TIME GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt); static unsigned long GetImageSize(BITMAPINFOHEADER* pbmih); }; //------------------------------------------------------------------------------ // UNITS = 10 ^ 7 // UNITS / 30 = 30 fps; // UNITS / 20 = 20 fps, etc const REFERENCE_TIME FPS_30 = UNITS / 30; const REFERENCE_TIME FPS_2997 = UNITS * 1001 / 30000; const REFERENCE_TIME FPS_25 = UNITS / 25; const REFERENCE_TIME FPS_24 = UNITS / 24; const REFERENCE_TIME FPS_23976 = UNITS * 1001 / 24000; const REFERENCE_TIME FPS_20 = UNITS / 20; const REFERENCE_TIME FPS_10 = UNITS / 10; const REFERENCE_TIME FPS_5 = UNITS / 5; const REFERENCE_TIME FPS_4 = UNITS / 4; const REFERENCE_TIME FPS_3 = UNITS / 3; const REFERENCE_TIME FPS_2 = UNITS / 2; const REFERENCE_TIME FPS_1 = UNITS / 1; //------------------------------------------------------------------------------ #define SAFE_DELETE(p){ if(p) { delete (p); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p){ if(p) { delete [] (p); (p)=NULL; } } #define SAFE_RELEASE(p){ if(p) { (p)- Release(); (p)=NULL; } } #define SIZEOF_ARRAY(x)(sizeof(x)/sizeof((x)[0]))
https://w.atwiki.jp/bmd_intensity/pages/34.html
キャプチャソフトやコーデックなど(キャプソフト50音順にしてみた)。 ※解説サイトなどはリンクの方に記載してください。 キャプチャ・プレビューソフトあかねキャプチャー2 アマレコTV くすのきTV Aggregat(アグレガート) くすのきTVHD ふぬああ QTRex コーデック・その他DScaler Deinterlace Filter huffyuv huffyuv日本語化パッチ huffyuvs huffyuv_mt FastCodec キャプチャ・プレビューソフト あかねキャプチャー2 あかねキャプチャー2はゲームプレイ&録画を前提としたDirectShowキャプチャーソフトです。 アマレコTV DirectShowに対応したフリーのビデオキャプチャアプリケーション 実行には別途AMVビデオコーデック(シェアウエア)が必用 録画中にHDDへの書き込み速度、CPUの負荷率などといったステータスがリアルタイムに表示され、自分のキャプチャー環境を知るバロメーターにもなる くすのきTV Aggregat(アグレガート) PSPからHDまで幅広い映像入力に対応したキャプチャソフトです。 2009/9/7 Ver0.01公開 2009/9/9 Ver0.02公開 2009/9/12 Ver0.03公開 2009/9/13 Ver0.04公開 2009/10/4 ver0.05公開 2010/1/24 ver0.06 ・1080p24に対応 ※Vistaへのインストール方法はこちら くすのきTVHD Intensityシリーズ専用ソフト 視聴専用だったが、このたび録画機能が付いた。多機能で扱いやすい ふぬああが苦手な人向け ふぬああ DirectShowベースのフリーキャプチャツール 細かな設定を行う事が出来るがその項目の多さに 初心者にはやや敷居が高い QTRex Macでキャプチャ・プレビューするならこちら 接続された外部入力源からの音声(映像)をQuickTime形式で録音(録画)するソフトです。 予約録音(録画)機能もあります。 コーデック・その他 DScaler Deinterlace Filter 重くなってしまうが綺麗にインターレース解除を行ってくれるフィルタ ふぬああインストール時と同じくregsvr32を行う必要がある huffyuv CPU負荷の低い可逆圧縮コーデック ソースをほとんど劣化させず無圧縮より小さいサイズで保存する事が可能 但し圧縮すると言っても圧縮率は低くHDDの書き込み速度には注意 huffyuv日本語化パッチ huffyuvの日本語化パッチ(公開停止?) 項目が多いわけではないので当てたい人用 huffyuvs MPEG2エンコーダの CinemaCraft Encoder に入力するときはこれを使ったほうが良いようです。 huffyuv_mt Huffyuv をベースに、ちょっと修正してマルチスレッド化したもの。MTモードでエンコードしたデータは、オリジナルのHuffyuvではデコードできないので注意。 FastCodec CPU負荷の低い可逆圧縮コーデック ソースをほとんど劣化させず無圧縮より小さいサイズで保存する事が可能 但し圧縮すると言っても圧縮率は低くHDDの書き込み速度には注意 Visualy Losslessを選ぶとhuffyuvより容量を減らす事が可能
https://w.atwiki.jp/intensity/pages/29.html
//----------------------------------------------------------------------------- // $Id DecklinkCaptureDlg.cpp,v 1.9 2006/04/11 01 11 07 ivanr Exp $ // // Desc DirectShow capture sample // // Copyright (c) Blackmagic Design 2005. All rights reserved. //----------------------------------------------------------------------------- #include "stdafx.h" #include "DecklinkCapture.h" #include "DecklinkCaptureDlg.h" #include initguid.h // TODO move this to a lib #include "DecklinkSample_uuids.h" #undef lstrlenW #ifdef _DEBUG #define new DEBUG_NEW #endif #define WM_GRAPHNOTIFYWM_APP+1// for Filter Graph event notification //----------------------------------------------------------------------------- // CAboutDlg //----------------------------------------------------------------------------- // CAboutDlg dialog used for App About class CAboutDlg public CDialog { public CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected DECLARE_MESSAGE_MAP() }; CAboutDlg CAboutDlg() CDialog(CAboutDlg IDD) { } void CAboutDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg dialog //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // Constructor // CDecklinkCaptureDlg CDecklinkCaptureDlg(CWnd* pParent /*=NULL*/) CDialog(CDecklinkCaptureDlg IDD, pParent) , m_pIVW(NULL) { m_hIcon = AfxGetApp()- LoadIcon(IDR_MAINFRAME); } //----------------------------------------------------------------------------- // DoDataExchange // void CDecklinkCaptureDlg DoDataExchange(CDataExchange* pDX) { CDialog DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO_VIDEOFORMATS, m_videoFormatCtrl); DDX_Control(pDX, IDC_COMBO_AUDIOFORMATS, m_audioFormatCtrl); DDX_Control(pDX, IDC_STATIC_PREVIEW, m_preview); DDX_Control(pDX, IDC_EDIT_CAPTUREFILE, m_captureFileCtrl); DDX_Control(pDX, IDC_COMBO_COMPRESSION, m_compressionCtrl); DDX_Control(pDX, IDC_COMBO_VIDEODEVICE, m_videoDeviceCtrl); DDX_Control(pDX, IDC_COMBO_AUDIODEVICE, m_audioDeviceCtrl); } BEGIN_MESSAGE_MAP(CDecklinkCaptureDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_COMBO_VIDEOFORMATS, OnCbnSelchangeComboVideoformats) ON_CBN_SELCHANGE(IDC_COMBO_AUDIOFORMATS, OnCbnSelchangeComboAudioformats) ON_BN_CLICKED(IDC_CHECK_AUDIOMUTE, OnBnClickedCheckAudiomute) ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse) ON_BN_CLICKED(IDC_BUTTON_CAPTURE, OnBnClickedButtonCapture) ON_BN_CLICKED(IDC_BUTTON_STOP, OnBnClickedButtonStop) ON_CBN_SELCHANGE(IDC_COMBO_COMPRESSION, OnCbnSelchangeComboCompression) ON_CBN_SELCHANGE(IDC_COMBO_VIDEODEVICE, OnCbnSelchangeComboVideodevice) ON_CBN_SELCHANGE(IDC_COMBO_AUDIODEVICE, OnCbnSelchangeComboAudiodevice) END_MESSAGE_MAP() //----------------------------------------------------------------------------- // CDecklinkCaptureDlg message handlers //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // OnInitDialog // Called before the dialog is displayed, use this message handler to initialise // our app BOOL CDecklinkCaptureDlg OnInitDialog() { CDialog OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu- AppendMenu(MF_SEPARATOR); pSysMenu- AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application s main window is not a dialog SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE);// Set small icon // create a basic capture graph and preview the incoming video m_pGraph = NULL; m_pVideoCapture = NULL; m_pAudioCapture = NULL; m_pVideoRenderer = NULL; m_pSmartT = NULL; m_pControl = NULL; m_pIVW = NULL; m_pMediaEvent = NULL; m_ROTRegister = 0; m_bAudioMute = FALSE; m_compressor = 0; m_bEnableCompressionCtrl = TRUE; m_captureFile = " Select File "; // initialise default video media type ZeroMemory( m_vihDefault, sizeof(m_vihDefault)); m_vihDefault.AvgTimePerFrame = 333667; m_vihDefault.bmiHeader.biWidth = 720; m_vihDefault.bmiHeader.biHeight = 486; m_vihDefault.bmiHeader.biBitCount = 16; m_vihDefault.bmiHeader.biCompression = YVYU ; // initialise default audio media type ZeroMemory( m_wfexDefault, sizeof(m_wfexDefault)); m_wfexDefault.nChannels = 2;// the only field of interest // retrieve last state QueryRegistry(); m_captureFileCtrl.SetWindowText(m_captureFile); EnableControls(); // create a preview graph // add the filters that will be used by all the graphs; preview, uncompressed capture, dv capture, // mpeg capture and windows media capture HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, reinterpret_cast void** ( m_pGraph)); if (SUCCEEDED(hr)) { #ifdef _DEBUG hr = CDSUtils AddGraphToRot(m_pGraph, m_ROTRegister); #endif hr = m_pGraph- QueryInterface(IID_IMediaControl, reinterpret_cast void** ( m_pControl)); if (SUCCEEDED(hr)) { // locate the video capture devices hr = PopulateDeviceControl( CLSID_VideoInputDeviceCategory, m_videoDeviceCtrl); if (SUCCEEDED(hr)) { hr = PopulateDeviceControl( CLSID_AudioInputDeviceCategory, m_audioDeviceCtrl); if (SUCCEEDED(hr)) { PWSTR pVideoName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.SetCurSel(0)); PWSTR pAudioName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.SetCurSel(0)); if (pVideoName pAudioName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pVideoName, m_pVideoCapture); if (SUCCEEDED(hr)) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pAudioName, m_pAudioCapture); if (SUCCEEDED(hr)) { PopulateVideoControl();// populate the video format control with the video formats of the currently selected device PopulateAudioControl();// populate the audio format control with the audio formats of the currently selected device PopulateCompressionControl(); // locate video screen renderer for the preview window hr = CDSUtils AddFilter(m_pGraph, CLSID_VideoRendererDefault, L"Video Renderer", m_pVideoRenderer); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); } } } } } } } } return TRUE; // return TRUE unless you set the focus to a control } //----------------------------------------------------------------------------- // DestroyWindow // Called when the window is being destroyed, clean up and free all resources. BOOL CDecklinkCaptureDlg DestroyWindow() { m_regUtils.Close(); #ifdef _DEBUG CDSUtils RemoveGraphFromRot(m_ROTRegister); #endif DestroyGraph(); SAFE_RELEASE(m_pControl); // Hide Video Window and remove owner. This has to be done prior to // destroying any window that displays video/still. if (m_pIVW) { m_pIVW- put_Visible(OAFALSE); m_pIVW- put_Owner(NULL); } SAFE_RELEASE(m_pIVW); SAFE_RELEASE(m_pMediaEvent); SAFE_RELEASE(m_pVideoRenderer); SAFE_RELEASE(m_pAudioCapture); SAFE_RELEASE(m_pVideoCapture); SAFE_RELEASE(m_pGraph); // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } count = m_audioFormatCtrl.GetCount(); for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } // release the device names attached to the item s data count = m_videoDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(item); delete [] pName; } count = m_audioDeviceCtrl.GetCount(); for (item=0; item count; ++item) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(item); delete [] pName; } return CDialog DestroyWindow(); } //----------------------------------------------------------------------------- // OnSysCommand // void CDecklinkCaptureDlg OnSysCommand(UINT nID, LPARAM lParam) { if ((nID 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog OnSysCommand(nID, lParam); } } //----------------------------------------------------------------------------- // OnPaint // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDecklinkCaptureDlg OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast WPARAM (dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect( rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog OnPaint(); } } //----------------------------------------------------------------------------- // HandleGraphEvent // At the moment we just read the event, discard it and release memory used to store it. void CDecklinkCaptureDlg HandleGraphEvent(void) { LONG lEventCode, lEventParam1, lEventParam2; if (!m_pMediaEvent) { return; } while (SUCCEEDED(m_pMediaEvent- GetEvent( lEventCode, reinterpret_cast LONG_PTR * ( lEventParam1), reinterpret_cast LONG_PTR * ( lEventParam2), 0))) { // just free memory associated with event m_pMediaEvent- FreeEventParams(lEventCode, lEventParam1, lEventParam2); } } //----------------------------------------------------------------------------- // WindowProc // Have to add our own message handling loop to handle events from the preview video // window and to pass Window events onto it - this is so it redraws itself correctly etc. LRESULT CDecklinkCaptureDlg WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_GRAPHNOTIFY HandleGraphEvent(); break; } // Pass all msgs to video window. vid window exists as child of static // picture frame. This ensures video window redraws itself etc. if (m_pIVW) { m_pIVW- NotifyOwnerMessage(reinterpret_cast LONG_PTR (m_hWnd) /* from me */, message, wParam, lParam); } return CDialog WindowProc(message, wParam, lParam); } //----------------------------------------------------------------------------- // OnQueryDragIcon // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDecklinkCaptureDlg OnQueryDragIcon() { return static_cast HCURSOR (m_hIcon); } //----------------------------------------------------------------------------- // CreatePreviewGraph // Create a graph to preview the input // NOTE There are many ways of building graphs, you could opt for the ICaptureGraphBuilder interface which would // make things are lot simpler, however it doesn t always build the most efficient graphs. HRESULT CDecklinkCaptureDlg CreatePreviewGraph() { HRESULT hr = S_OK; if (m_pGraph) { // locate smart-T // NOTE The smart-T appears to hold references to its upstream connections even when its input pin // is diconnected. The smart-T has to be removed from the graph in order to clear these references which // is why the filter is enumerated and added every time the preview graph is built and removed whenever // it is destroyed. ASSERT(NULL == m_pSmartT); hr = CDSUtils AddFilter(m_pGraph, CLSID_SmartTee, L"Smart Tee", m_pSmartT); if (SUCCEEDED(hr)) { // DV preview is slightly different to all other previews if (ENC_DV != m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { // uncompressed, mpeg and wm preview // create the following // // Decklink Video Capture - Smart-T - AVI Decompressor - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // render the preview pin on the smart-T filter // first connect the Decklink video capture pin to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // now connect the preview pin of the smart-T to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", m_pVideoRenderer, NULL); } } else { // DV Preview // create the following // // Decklink Video Capture - AVI Decompressor - Smart-T - Colour Space Converter - Video Renderer // Decklink Audio Capture - Default Audio Renderer // // this is a more efficient graph than created by the ICaptureGraphBuilder2 interface // add the AVI decompressor and colour space converter filters CComPtr IBaseFilter pAVIDecompressor = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AVIDec, L"AVI Decompressor", pAVIDecompressor); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pColourSpaceConverter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_Colour, L"Color Space Converter", pColourSpaceConverter); if (SUCCEEDED(hr)) { // conect the Decklink video capture pin to the AVI decompressor hr = CDSUtils ConnectFilters(m_pGraph, m_pVideoCapture, NULL, pAVIDecompressor, NULL); if (SUCCEEDED(hr)) { // connect AVI decompressor to the smart-T hr = CDSUtils ConnectFilters(m_pGraph, pAVIDecompressor, NULL, m_pSmartT, NULL); if (SUCCEEDED(hr)) { // connect the preview pin of the smart-T to the colour space converter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Preview", pColourSpaceConverter, NULL); if (SUCCEEDED(hr)) { // connect the colour space converter to the video renderer hr = CDSUtils ConnectFilters(m_pGraph, pColourSpaceConverter, NULL, m_pVideoRenderer, NULL); } } } } } } } } else { hr = E_POINTER; } if (SUCCEEDED(hr)) { // the video path has been connected, initialise the preview window InitialiseVideoPreview(); // optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils RenderFilter(m_pGraph, m_pAudioCapture, L"Capture"); } // run the graph so that we can preview the input video if (m_pControl) { hr = m_pControl- Run(); } else { hr = E_POINTER; } } return hr; } //----------------------------------------------------------------------------- // CreateCaptureGraph // Create a graph to capture the input HRESULT CDecklinkCaptureDlg CreateCaptureGraph() { HRESULT hr = S_OK; // tack the file writer onto the preview graph if (m_pGraph m_pControl) { // stop the graph as we are about to modify it m_pControl- Stop(); // remove the default audio renderer so the Decklink audio capture filter // can be connected to the AVI mux, we will not preview audio whilst capturing CComPtr IPin pIPinOutput = NULL; hr = CDSUtils GetPin(m_pAudioCapture, L"Capture", pIPinOutput); if (SUCCEEDED(hr)) { // to disconnect both pins must be disconnected // find the pin connected to the Decklink audio capture pin CComPtr IPin pIPinConnection = NULL; hr = pIPinOutput- ConnectedTo( pIPinConnection); if (SUCCEEDED(hr)) { // disconnect the pins hr = m_pGraph- Disconnect(pIPinOutput); hr = m_pGraph- Disconnect(pIPinConnection); // get the owning filter of the downstream pin and remove it from the graph PIN_INFO pinInfo = {0}; hr = pIPinConnection- QueryPinInfo( pinInfo); if (SUCCEEDED(hr)) { if (pinInfo.pFilter) { hr = m_pGraph- RemoveFilter(pinInfo.pFilter); pinInfo.pFilter- Release(); } } } } // retrieve the capture filename m_captureFileCtrl.GetWindowText(m_captureFile); // store filename USES_CONVERSION; WCHAR captureFile[MAX_PATH]; wcsncpy(captureFile, A2W(m_captureFile), MAX_PATH); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetString("CaptureFile", reinterpret_cast const BYTE* (captureFile), sizeof(captureFile))); // decide the type of capture graph to build switch (m_compressionCtrl.GetItemData(m_compressionCtrl.GetCurSel())) { default case ENC_NONE hr = CreateUncompressedCaptureGraph(); break; case ENC_DV hr = CreateDVCaptureGraph(); break; case ENC_WM hr = CreateWMCaptureGraph(); break; } if (FAILED(hr)) { // there was a problem building the capture graph, issue a message // and rebuild preview graph char buffer[128]; StringCbPrintfA(buffer, sizeof(buffer), "The error 0x%08lx was detected when creating the capture graph with the following file name \r\n\r\n %s ", hr, m_captureFile); MessageBox(buffer, _T("Error"), MB_ICONERROR); OnBnClickedButtonStop();// destroy broken capture graph, build preview graph and enable controls } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // CreateUncompressedCaptureGraph // Create an optimum uncompressed capture graph HRESULT CDecklinkCaptureDlg CreateUncompressedCaptureGraph() { HRESULT hr = S_OK; // uncompressed capture // locate the AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateDVCaptureGraph // Create an optimum DV capture graph // NOTE that this will only work for SD HRESULT CDecklinkCaptureDlg CreateDVCaptureGraph() { HRESULT hr = S_OK; // locate the DV encoder, AVI mux and file writer filters and add them to the graph CComPtr IBaseFilter pDVEncoder = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DVVideoEnc, L"DV Video Encoder", pDVEncoder); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pAVIMux = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_AviDest , L"AVI Mux", pAVIMux); if (SUCCEEDED(hr)) { CComPtr IBaseFilter pFileWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_FileWriter, L"File writer", pFileWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pFileWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { // configure the DV encoder CComQIPtr IDVEnc, IID_IDVEnc pIDV = pDVEncoder; if (pIDV) { // located a DV compression filter, set the format int videoFormat, dvFormat, resolution; hr = pIDV- get_IFormatResolution( videoFormat, dvFormat, resolution, FALSE, NULL); if (SUCCEEDED(hr)) { ASSERT(DVENCODERFORMAT_DVSD == dvFormat); ASSERT(DVENCODERRESOLUTION_720x480 == resolution); if ((DVENCODERVIDEOFORMAT_NTSC == videoFormat) (576 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to PAL if its NTSC videoFormat = DVENCODERVIDEOFORMAT_PAL; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } else if ((DVENCODERVIDEOFORMAT_PAL == videoFormat) (486 == m_vihDefault.bmiHeader.biHeight)) { // set the encoder to NTSC if its PAL videoFormat = DVENCODERVIDEOFORMAT_NTSC; hr = pIDV- put_IFormatResolution(videoFormat, dvFormat, resolution, FALSE, NULL); } } } if (SUCCEEDED(hr)) { // if the format is PAL, insert the Decklink field swap filter, PAL DV is the opposite // field order to PAL SD if (576 == m_vihDefault.bmiHeader.biHeight) { CComPtr IBaseFilter pPALFieldSwap = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_DecklinkFieldSwap, L"Decklink PAL Field Swap", pPALFieldSwap); if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the PAL field swap filter hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pPALFieldSwap, NULL); if (SUCCEEDED(hr)) { // connect the field swap filter to the DV encoder hr = CDSUtils ConnectFilters(m_pGraph, pPALFieldSwap, NULL, pDVEncoder, NULL); } } } else { // connect the smart-T capture pin to the DV Encoder hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, L"Capture", pDVEncoder, NULL); } if (SUCCEEDED(hr)) { // connect the DV encoder output to the AVI mux hr = CDSUtils ConnectFilters(m_pGraph, pDVEncoder, NULL, pAVIMux, NULL); if (SUCCEEDED(hr)) { // connect the mux to the file writer hr = CDSUtils ConnectFilters(m_pGraph, pAVIMux, NULL, pFileWriter, NULL); if (SUCCEEDED(hr)) { // video path connected now optionally connect the audio path if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the mux hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, L"Capture", pAVIMux, NULL); } if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } } } } } } } return hr; } //----------------------------------------------------------------------------- // CreateWMCaptureGraph // Create an optimum Windows Media capture graph HRESULT CDecklinkCaptureDlg CreateWMCaptureGraph() { HRESULT hr = S_OK; // locate the asf writer filter and add it to the graph CComPtr IBaseFilter pASFWriter = NULL; hr = CDSUtils AddFilter(m_pGraph, CLSID_WMAsfWriter, L"WM ASF Writer", pASFWriter); if (SUCCEEDED(hr)) { // set the output filename CComQIPtr IFileSinkFilter, IID_IFileSinkFilter pIFS = pASFWriter; if (pIFS) { USES_CONVERSION;// for T2W macro hr = pIFS- SetFileName(T2W(m_captureFile), NULL); if (SUCCEEDED(hr)) { hr = ConfigureWMEncoder(pASFWriter); } } if (SUCCEEDED(hr)) { if (FALSE == m_bAudioMute) { // connect the Decklink audio capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pAudioCapture, pASFWriter, MEDIATYPE_Audio); } if (SUCCEEDED(hr)) { // connect the smart-T capture pin to the ASF writer hr = CDSUtils ConnectFilters(m_pGraph, m_pSmartT, pASFWriter, MEDIATYPE_Video); if (SUCCEEDED(hr)) { m_pControl- Run(); } } } } return hr; } //----------------------------------------------------------------------------- // ConfigureWMEncoder // Configure the Windows Media encoder HRESULT CDecklinkCaptureDlg ConfigureWMEncoder(IBaseFilter* pASFWriter) { HRESULT hr = S_OK; // modify the video output resolution of a system profile if (pASFWriter) { // simple system profile encoding CComQIPtr IConfigAsfWriter, IID_IConfigAsfWriter pICW = pASFWriter; if (pICW) { //NOTE You could just use the following for a default system profile //hr = pICW- ConfigureFilterUsingProfileGuid(WMProfile_XXX);// RE wmsysprf.h //NOTE If you want video only capture you must modify the profile to remove the audio // otherwise encoding will fail // Load a system profile and modify the resolution of the video output // NOTE The scope of the encoding is enormous, this just demonstrates how to change // the output video resolution from 320x240 to something larger. // Changing the resolution affects coding performance, it is likely that the encoder will // start to drop frames after a while. Using WM9 codecs will probably improve performance // and that has been left to the reader... ;o) // // get a profile manager CComPtr IWMProfileManager pIWMProfileManager = NULL; hr = WMCreateProfileManager( pIWMProfileManager); if (SUCCEEDED(hr)) { // load a system profile to modify CComPtr IWMProfile pIWMProfile = NULL; // NOTE Any WMProfile_XXX could be used here, or create a custom profile from scratch hr = pIWMProfileManager- LoadProfileByID(WMProfile_V80_FAIRVBRVideo, pIWMProfile); if (SUCCEEDED(hr)) { // search the streams for the video stream and attempt to modify the video size DWORD cbStreams = 0; hr = pIWMProfile- GetStreamCount( cbStreams); if (SUCCEEDED(hr)) { IWMStreamConfig* pIWMStreamConfig = NULL; GUID streamType = {0}; DWORD stream; if (m_bAudioMute) { // remove the audio stream for video only capture for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr)) { if (MEDIATYPE_Audio == streamType) { if (SUCCEEDED(pIWMProfile- RemoveStream(pIWMStreamConfig))) { --cbStreams; } SAFE_RELEASE(pIWMStreamConfig); break; } } } } } for (stream=0; stream cbStreams; ++stream) { hr = pIWMProfile- GetStream(stream, pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pIWMStreamConfig- GetStreamType( streamType); if (SUCCEEDED(hr) (MEDIATYPE_Video == streamType)) { // found the video stream CComQIPtr IWMMediaProps, IID_IWMMediaProps pIWMMediaProps = pIWMStreamConfig; if (pIWMMediaProps) { // get the size of the media type WM_MEDIA_TYPE* pMediaType = NULL; DWORD cbMediaType = 0; hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { pMediaType = (WM_MEDIA_TYPE*)new char [cbMediaType]; if (pMediaType) { hr = pIWMMediaProps- GetMediaType(pMediaType, cbMediaType); if (SUCCEEDED(hr)) { BITMAPINFOHEADER* pbmih = NULL; if (WMFORMAT_VideoInfo == pMediaType- formattype) { WMVIDEOINFOHEADER* pvih = (WMVIDEOINFOHEADER*)pMediaType- pbFormat; pbmih = pvih- bmiHeader; } else if (WMFORMAT_MPEG2Video == pMediaType- formattype) { WMVIDEOINFOHEADER2* pvih = (WMVIDEOINFOHEADER2*) ((WMMPEG2VIDEOINFO*)pMediaType- pbFormat)- hdr; pbmih = pvih- bmiHeader; } if (pbmih) { // modify the video dimensions, set the property, reconfigure the stream // and then configure the ASF writer with this modified profile pbmih- biWidth = 640;// was 320; pbmih- biHeight = 480;// was 240; pbmih- biSizeImage = pbmih- biWidth * pbmih- biHeight * pbmih- biBitCount / 8;// NOTE This calculation is not correct for all bit depths hr = pIWMMediaProps- SetMediaType(pMediaType); if (SUCCEEDED(hr)) { // config the ASF writer filter to use this modified system profile hr = pIWMProfile- ReconfigStream(pIWMStreamConfig); if (SUCCEEDED(hr)) { hr = pICW- ConfigureFilterUsingProfile(pIWMProfile); } } } } delete [] (char*)pMediaType; } } } } SAFE_RELEASE(pIWMStreamConfig); } } } } } /* // modify other ASF writer properties IServiceProvider* pProvider = NULL; hr = pASFWriter- QueryInterface(IID_IServiceProvider, reinterpret_cast void** ( pProvider)); if (SUCCEEDED(hr)) { IID_IWMWriterAdvanced2* pWMWA2 = NULL; hr = pProvider- QueryService(IID_IID_IWMWriterAdvanced2, IID_IID_IWMWriterAdvanced2, reinterpret_cast void** ( pWMWA2)); if (SUCCEEDED(hr)) { // set the deinterlace mode pWMWA2- GetInputSetting(...); SAFE_RELEASE(pWMWA2); } SAFE_RELEASE(pProvider); } */ } } else { hr = E_INVALIDARG; } return hr; } //----------------------------------------------------------------------------- // DestroyGraph // Remove all intermediate filters, keep any Decklink and video render filters as // these are used by all the graphs. HRESULT CDecklinkCaptureDlg DestroyGraph() { HRESULT hr = S_OK; if (m_pGraph m_pControl) { m_pControl- Stop(); // release our outstanding reference on this filter so it can be removed from the graph SAFE_RELEASE(m_pSmartT); // retrieve the name of the capture device, don t remove it in this method PWSTR pNameVideoCapture = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); PWSTR pNameAudioCapture = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); CComPtr IEnumFilters pEnum = NULL; hr = m_pGraph- EnumFilters( pEnum); if (SUCCEEDED(hr)) { IBaseFilter* pFilter = NULL; while (S_OK == pEnum- Next(1, pFilter, NULL)) { FILTER_INFO filterInfo = {0}; hr = pFilter- QueryFilterInfo( filterInfo); if (SUCCEEDED(hr)) { SAFE_RELEASE(filterInfo.pGraph); if ((NULL == wcsstr(filterInfo.achName, pNameVideoCapture)) (NULL == wcsstr(filterInfo.achName, pNameAudioCapture)) (NULL == wcsstr(filterInfo.achName, L"Video Renderer"))) { hr = m_pGraph- RemoveFilter(pFilter); if (SUCCEEDED(hr)) { hr = pEnum- Reset(); } } } SAFE_RELEASE(pFilter); } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // InitialiseVideoPreview // In short get the video screen renderer to draw into the picture control, which is our preview window // the following code sets this up, in addition to adding the HandleGraphEvent and WindowProc methods // read the DXSDK docos for more detailed information void CDecklinkCaptureDlg InitialiseVideoPreview(void) { // modify the preview window if (m_pVideoRenderer) { if (NULL == m_pIVW) { if (SUCCEEDED(m_pVideoRenderer- QueryInterface(IID_IVideoWindow, reinterpret_cast void** ( m_pIVW)))) { // get the window to handle redraws, etc // Set msg drain of VideoWindow to point to our dialog window. The dialog s // window procedure then handles events from the VideoWindow. HRESULT hr = m_pIVW- put_MessageDrain(reinterpret_cast OAHWND (m_hWnd)); if (NULL == m_pMediaEvent) { // Make graph send WM_GRAPHNOTIFY when it wants our attention see "Learning // When an Event Occurs" in the DX9 documentation. hr = m_pGraph- QueryInterface(IID_IMediaEventEx, reinterpret_cast void** ( m_pMediaEvent)); if (SUCCEEDED(hr)) { hr = m_pMediaEvent- SetNotifyWindow(reinterpret_cast OAHWND (m_hWnd), WM_GRAPHNOTIFY, 0); } // object created for it. RECT rc; m_preview.GetClientRect( rc); m_pIVW- SetWindowPosition(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); // VideoWindow is a child window of the bounding rect hr = m_pIVW- put_WindowStyle(WS_CHILD); hr = m_pIVW- put_Owner(reinterpret_cast OAHWND (m_preview.GetSafeHwnd())); hr = m_pIVW- SetWindowForeground(-1); } } } } } //----------------------------------------------------------------------------- // PopulateDeviceControl // Fill device combo box with available devices of the specified category HRESULT CDecklinkCaptureDlg PopulateDeviceControl(const GUID* pCategory, CComboBox* pCtrl) { HRESULT hr = S_OK; if (pCategory pCtrl) { // first enumerate the system devices for the specifed class and filter name CComPtr ICreateDevEnum pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast void** ( pSysDevEnum)); if (SUCCEEDED(hr)) { CComPtr IEnumMoniker pEnumCat = NULL; hr = pSysDevEnum- CreateClassEnumerator(*pCategory, pEnumCat, 0); if (S_OK == hr) { IMoniker* pMoniker = NULL; bool Loop = true; while ((S_OK == pEnumCat- Next(1, pMoniker, NULL)) Loop) { IPropertyBag* pPropBag = NULL; hr = pMoniker- BindToStorage(0, 0, IID_IPropertyBag, reinterpret_cast void** ( pPropBag)); if (SUCCEEDED(hr)) { VARIANT varName; VariantInit( varName); hr = pPropBag- Read(L"FriendlyName", varName, 0); if (SUCCEEDED(hr)) { size_t len = wcslen(varName.bstrVal) + 1; PWSTR pName = new WCHAR [len]; StringCchCopyW(pName, len, varName.bstrVal); CW2AEX buf(varName.bstrVal); pCtrl- SetItemData(pCtrl- AddString(buf), (DWORD)pName); } VariantClear( varName); // contained within a loop, decrement the reference count SAFE_RELEASE(pPropBag); } SAFE_RELEASE(pMoniker); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateVideoControl // Fill video format combo box with supported video formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateVideoControl() { HRESULT hr = S_OK; if (m_pVideoCapture) { // free mediatypes attached to format controls int count = m_videoFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(item)); } m_videoFormatCtrl.ResetContent(); } // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (video formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(VIDEO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; VIDEO_STREAM_CONFIG_CAPS vscc; VIDEOINFOHEADER* pvih = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( vscc)); if (SUCCEEDED(hr)) { char buffer[128]; WORD PixelFormat; float FrameRate; ZeroMemory(buffer, sizeof(buffer)); pvih = (VIDEOINFOHEADER*)pmt- pbFormat; char* pPixelFormatLUT[] = {"4 2 2", "4 4 4"}; if (pvih- bmiHeader.biBitCount == 16) PixelFormat = 8; else if (pvih- bmiHeader.biBitCount == 20) PixelFormat = 10; else PixelFormat = pvih- bmiHeader.biBitCount; // provide a useful description of the formats if (486 == pvih- bmiHeader.biHeight) { if (417083 == pvih- AvgTimePerFrame) { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s (3 2 pulldown removal)", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "NTSC %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if (576 == pvih- bmiHeader.biHeight) { StringCbPrintfA(buffer, sizeof(buffer), "PAL %d-bit %s", PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { char* pFrameRateFormat[] = {"%.2f", "%.0f"}; FrameRate = (float)(long)UNITS / pvih- AvgTimePerFrame; if ((720 == pvih- bmiHeader.biHeight) (59.94 FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s (Overcranked 60p)", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((720 == pvih- bmiHeader.biHeight) (59.94 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.2fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD720 %.0fp %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else if ((1080 == pvih- bmiHeader.biHeight) (50.00 = FrameRate)) { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fi %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } else { if ((FrameRate - (int)FrameRate) 0.01) { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.2fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } else { StringCbPrintfA(buffer, sizeof(buffer), "HD1080 %.0fPsF %d-bit %s", FrameRate, PixelFormat, pPixelFormatLUT[(30 == PixelFormat)]); } } } // add the item description to combo box int n = m_videoFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_videoFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pvih- AvgTimePerFrame == m_vihDefault.AvgTimePerFrame) (pvih- bmiHeader.biWidth == m_vihDefault.bmiHeader.biWidth) (pvih- bmiHeader.biHeight == m_vihDefault.bmiHeader.biHeight) (pvih- bmiHeader.biBitCount == m_vihDefault.bmiHeader.biBitCount)) { m_videoFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_videoFormatCtrl.AddString("ERROR Unable to retrieve video formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateAudioControl // Fill audio format combo box with supported audio formats using the IAMStreamConfig // interface. HRESULT CDecklinkCaptureDlg PopulateAudioControl() { HRESULT hr = S_OK; if (m_pAudioCapture) { // free mediatypes attached to format controls int count = m_audioFormatCtrl.GetCount(); if (count) { for (int item=0; item count; ++item) { DeleteMediaType((AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(item)); } m_audioFormatCtrl.ResetContent(); } // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // loop through all the capabilities (audio formats) and populate the control int count, size; hr = pISC- GetNumberOfCapabilities( count, size); if (SUCCEEDED(hr)) { if (sizeof(AUDIO_STREAM_CONFIG_CAPS) == size) { AM_MEDIA_TYPE* pmt = NULL; AUDIO_STREAM_CONFIG_CAPS ascc; WAVEFORMATEX* pwfex = NULL; for (int index=0; index count; ++index) { hr = pISC- GetStreamCaps(index, pmt, reinterpret_cast BYTE* ( ascc)); if (SUCCEEDED(hr)) { char buffer[32]; ZeroMemory(buffer, sizeof(buffer)); pwfex = (WAVEFORMATEX*)pmt- pbFormat; // provide a useful description of the formats if (1 == pwfex- nChannels) { StringCbPrintfA(buffer, sizeof(buffer), "%d channel, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } else { StringCbPrintfA(buffer, sizeof(buffer), "%d channels, %2.1fkHz, %d-bit", (int)pwfex- nChannels, (float)pwfex- nSamplesPerSec / 1000, (int)pwfex- wBitsPerSample); } // add the item description to combo box int n = m_audioFormatCtrl.AddString(buffer); // store media type pointer in item s data section m_audioFormatCtrl.SetItemData(n, (DWORD_PTR)pmt); // set default format if ((pwfex- wFormatTag == m_wfexDefault.wFormatTag) (pwfex- nChannels == m_wfexDefault.nChannels) (pwfex- nSamplesPerSec == m_wfexDefault.nSamplesPerSec) (pwfex- nAvgBytesPerSec == m_wfexDefault.nAvgBytesPerSec)) { m_audioFormatCtrl.SetCurSel(n); pISC- SetFormat(pmt); } } } } else { m_audioFormatCtrl.AddString("ERROR Unable to retrieve audio formats"); } } } } else { hr = E_POINTER; } return hr; } //----------------------------------------------------------------------------- // PopulateCompressionControl // Fill compression control with a selection of video compressors, locate the // encoders and add them to the combo box if they exist. HRESULT CDecklinkCaptureDlg PopulateCompressionControl() { int n = m_compressionCtrl.AddString("Uncompressed"); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_NONE); // search for the DV encoder, MPEG encoder and WM encoder IBaseFilter* pFilter = NULL; HRESULT hr = CoCreateInstance(CLSID_DVVideoEnc, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("DV Video Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_DV); SAFE_RELEASE(pFilter); } hr = CoCreateInstance(CLSID_WMAsfWriter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, reinterpret_cast void** ( pFilter)); if (SUCCEEDED(hr)) { n = m_compressionCtrl.SetCurSel(m_compressionCtrl.AddString("Windows Media Encoder")); m_compressionCtrl.SetItemData(n, (DWORD_PTR)ENC_WM); SAFE_RELEASE(pFilter); } m_compressionCtrl.SetCurSel(m_compressor); return S_OK; } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboVideodevice() { SAFE_RELEASE(m_pVideoCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // rebuild graph with new capture device selection PWSTR pName = (PWSTR)m_videoDeviceCtrl.GetItemData(m_videoDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_VideoInputDeviceCategory, pName, m_pVideoCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_vihDefault = *(VIDEOINFOHEADER*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateVideoControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudiodevice // Rebuild graph with selected capture device void CDecklinkCaptureDlg OnCbnSelchangeComboAudiodevice() { SAFE_RELEASE(m_pAudioCapture);// release our outstanding reference // remove intermediate filters, since the device selection has changed the capture device will also be removed HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { PWSTR pName = (PWSTR)m_audioDeviceCtrl.GetItemData(m_audioDeviceCtrl.GetCurSel()); if (pName) { hr = CDSUtils AddFilter2(m_pGraph, CLSID_AudioInputDeviceCategory, pName, m_pAudioCapture); if (SUCCEEDED(hr)) { // as the device has changed get the current operating format so that the control // and display this as the current selection CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // get the current format of the device to set the current selection of the control AM_MEDIA_TYPE* pamt = NULL; hr = pISC- GetFormat( pamt); if (SUCCEEDED(hr)) { if (pamt- pbFormat) { m_wfexDefault = *(WAVEFORMATEX*)pamt- pbFormat; } DeleteMediaType(pamt); } } hr = PopulateAudioControl();// repopulate the control with formats from the new device if (SUCCEEDED(hr)) { hr = CreatePreviewGraph();// rebuild the graph with the new device } } } else { hr = E_POINTER; } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboVideoformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboVideoformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the video capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pVideoCapture, MEDIATYPE_Video, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_videoFormatCtrl.GetItemData(m_videoFormatCtrl.GetCurSel()); m_vihDefault = *(VIDEOINFOHEADER*)pmt- pbFormat; ASSERT(sizeof(VIDEOINFOHEADER) = pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); // update compression control, we don t have an HD compression filter so disable compression for HD formats if (576 m_vihDefault.bmiHeader.biHeight) { m_compressor = 0; m_compressionCtrl.SetCurSel(m_compressor); // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); m_bEnableCompressionCtrl = FALSE; } else { m_bEnableCompressionCtrl = TRUE; } EnableControls(); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboAudioformats // Rebuild preview graph if format selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboAudioformats() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // locate the audio capture pin and QI for stream control CComPtr IAMStreamConfig pISC = NULL; hr = CDSUtils FindPinInterface(m_pAudioCapture, MEDIATYPE_Audio, PINDIR_OUTPUT, IID_IAMStreamConfig, reinterpret_cast void** ( pISC)); if (SUCCEEDED(hr)) { // set the new media format AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)m_audioFormatCtrl.GetItemData(m_audioFormatCtrl.GetCurSel()); m_wfexDefault = *(WAVEFORMATEX*)pmt- pbFormat; ASSERT(sizeof(WAVEFORMATEX) == pmt- cbFormat); hr = pISC- SetFormat(pmt); if (SUCCEEDED(hr)) { // save the new format EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); // rebuild the graph hr = CreatePreviewGraph(); } } } } //----------------------------------------------------------------------------- // OnCbnSelchangeComboCompression // Rebuild preview graph if compression selection changed void CDecklinkCaptureDlg OnCbnSelchangeComboCompression() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state m_compressor = m_compressionCtrl.GetCurSel(); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); // rebuild the graph hr = CreatePreviewGraph(); } } //----------------------------------------------------------------------------- // OnBnClickedCheckAudiomute // Rebuild the capture graph to reflect the new audio setting void CDecklinkCaptureDlg OnBnClickedCheckAudiomute() { CButton* pCheck = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); if (pCheck) { m_bAudioMute = pCheck- GetState() 0x0003; HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { // save the new state EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); // rebuild the graph which reflects the new audio setting hr = CreatePreviewGraph(); } } } //----------------------------------------------------------------------------- // OnBnClickedButtonBrowse // Create a file open dialog to browse for a file location void CDecklinkCaptureDlg OnBnClickedButtonBrowse() { char BASED_CODE szFilters[] = "Windows Media Files|*.avi;*.asf;*.wmv|All Files (*.*)|*.*||"; char* pExt[] = {"*.avi", "*.avi", "*.asf;*.wmv"}; CFileDialog FileDlg(TRUE, "Windows Media Files", pExt[m_compressor], 0, szFilters, this); if (FileDlg.DoModal() == IDOK) { m_captureFile = FileDlg.GetPathName(); m_captureFileCtrl.SetWindowText(m_captureFile); } } //----------------------------------------------------------------------------- // OnBnClickedButtonCapture // Create a capture graph a start capture void CDecklinkCaptureDlg OnBnClickedButtonCapture() { HRESULT hr = CreateCaptureGraph(); if (SUCCEEDED(hr)) { if (m_pControl) { hr = m_pControl- Run(); if (SUCCEEDED(hr)) { DisableControls(); } } } } //----------------------------------------------------------------------------- // OnBnClickedButtonStop // Stop capture and revert to preview void CDecklinkCaptureDlg OnBnClickedButtonStop() { HRESULT hr = DestroyGraph(); if (SUCCEEDED(hr)) { hr = CreatePreviewGraph(); if (SUCCEEDED(hr)) { EnableControls(); } } } //----------------------------------------------------------------------------- // EnableControls // void CDecklinkCaptureDlg EnableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); m_bEnableCompressionCtrl = (576 m_vihDefault.bmiHeader.biHeight) ? FALSE TRUE;// don t have an HDV codec do disable compression control for HD formats pWnd- EnableWindow(m_bEnableCompressionCtrl); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(TRUE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(FALSE); } //----------------------------------------------------------------------------- // DisableControls // void CDecklinkCaptureDlg DisableControls(void) { CWnd* pWnd = GetDlgItem(IDC_COMBO_VIDEOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_AUDIOFORMATS); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_CHECK_AUDIOMUTE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_COMBO_COMPRESSION); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_EDIT_CAPTUREFILE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_BROWSE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_CAPTURE); pWnd- EnableWindow(FALSE); pWnd = GetDlgItem(IDC_BUTTON_STOP); pWnd- EnableWindow(TRUE); } //----------------------------------------------------------------------------- // QueryRegistry // retrieve previous media formats from registry void CDecklinkCaptureDlg QueryRegistry(void) { if (ERROR_SUCCESS == m_regUtils.Open("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoFormat", reinterpret_cast LPBYTE ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioFormat", reinterpret_cast LPBYTE ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("AudioMute", reinterpret_cast LPBYTE ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetBinary("VideoCompressor", reinterpret_cast LPBYTE ( m_compressor), sizeof(m_compressor))); WCHAR captureFile[MAX_PATH]; ZeroMemory(captureFile, sizeof(captureFile)); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.GetString("CaptureFile", reinterpret_cast LPBYTE (captureFile), sizeof(captureFile))); m_captureFile = captureFile; } else { // create the key and registry values if (ERROR_SUCCESS == m_regUtils.Create("DecklinkCaptureSample")) { EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoFormat", reinterpret_cast const BYTE* ( m_vihDefault), sizeof(m_vihDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioFormat", reinterpret_cast const BYTE* ( m_wfexDefault), sizeof(m_wfexDefault))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("AudioMute", reinterpret_cast const BYTE* ( m_bAudioMute), sizeof(m_bAudioMute))); EXECUTE_ASSERT(ERROR_SUCCESS == m_regUtils.SetBinary("VideoCompressor", reinterpret_cast const BYTE* ( m_compressor), sizeof(m_compressor))); } } // update mute audio check box control CButton* pButton = (CButton*)GetDlgItem(IDC_CHECK_AUDIOMUTE); pButton- SetCheck(m_bAudioMute); }
https://w.atwiki.jp/bmd_intensity/pages/17.html
開発環境(Visual C++) ファイル別処理内訳 /common/Utils.cpp Utils.h定義クラス処理 /include/Utils.h クラス定義ヘッダ /include/DecklinkInterface.h ドライバ制御(?) DecklinkCapture.h クラス定義ヘッダ DecklinkCaptureDlg.h フォーム処理定義ヘッダ resource.h winアプリフォームID管理 stdafx.h 他ヘッダーの読み込みとwinアプリ定義 DecklinkCapture.cpp DecklinkCapture.h定義クラス処理 DecklinkCaptureDlg.cpp DecklinkCaptureDlg.h定義クラス処理 stdafx.cpp クラス(/include/Utils.h) CDSUtils AddFilter(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) フィルター追加 説明:Attempts to locate a filter of a given class ID and nameand add it to the graph AddFilter2(IGraphBuilder* pGraph, const GUID clsid, LPCWSTR pName, IBaseFilter** ppFilter) フィルター追加 説明:Attempts to locate a filter of a given class category and name RemoveGraphFromRot(DWORD pdwRegister) レジストからフィルター読み込み 説明:Removes a filter graph from the Running Object Table GetUnconnectedPin(IBaseFilter* pFilter, PIN_DIRECTION PinDir, IPin** ppPin) 説明:Attemptes to locate an unconnected pin on filter GetPin(IBaseFilter* pFilter, const wchar_t* pName, IPin** ppPin) 説明:Find the pin of the specified name on the given filter This method leaves an outstanding reference on the pin if successful GetPin(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, IPin** ppPin) 説明:Find the pin of the specified format type on the given filter This method leaves an outstanding reference on the pin if successful ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName, IBaseFilter* pDownstream, wchar_t* pDownstreamPinName) 説明:Connects two filters using the pin names, if no name is supplied the first unconnected pin is used ConnectFilters(IGraphBuilder* pGraph, IBaseFilter* pUpstream, IBaseFilter* pDownstream, const GUID* pFormat) 説明:Connects two filters by finding a pin on the upstream filter with the specified major format type, e.g. For connecting an audio pin to a downstream filter RenderFilter(IGraphBuilder* pGraph, IBaseFilter* pUpstream, wchar_t* pUpstreamPinName) 説明:Renders the named output pin of the filter, or the first unconnected output if no name is provided DisconnectAllPins(IGraphBuilder* pGraph) 説明:Disconnect all the pins of the filters in a graph FindFilterInterface(IBaseFilter* pFilter, const IID riid, void** ppvInterface) 説明:Attempt to locate the specified interface FindPinInterface(IBaseFilter* pFilter, wchar_t* pName, const IID riid, void** ppvInterface) 説明:Attempt to locate the interface on the named pin or on the first pin if no name is provided. FindPinInterface(IBaseFilter* pFilter, const GUID* pFormat, PIN_DIRECTION PinDir, const IID riid, void** ppvInterface) 説明:Attempt to locate the interface on the pin with the specified format or on the first pin if no format is provided. AddGraphToRot(IUnknown* pUnkGraph, DWORD* pdwRegister) 説明:Adds a DirectShow filter graph to the Running Object Table, allowing GraphEdit to "spy" on a remote filter graph. CRegUtils CRegUtils() レジストリ取得 説明:Constructor ~CRegUtils() レジストリ閉じる 説明:Destructor Open(LPCTSTR lpSubKey) サブキーオープン 説明:Opens the specified subkey Create(LPCTSTR lpSubKey) サブキー生成 説明:Creates the specified subkey Close() サブキー終了 説明:Closes the subkey SetString(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) string形式設定 説明:Set the key for the named value of type string GetString(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) string取得 説明:Query the key for the named value of type string SetBinary(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) バイナリ形式設定 説明:Set the key for the named value of type binary GetBinary(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) バイナリ取得 説明:Query the key for the named value of type binary SetDword(LPCTSTR valueName, const BYTE* lpData, DWORD cbData) Dword形式設定 説明:Set the key for the named value of type DWORD GetDword(LPCTSTR valueName, LPBYTE lpData, DWORD cbData) Dword取得 説明:Query the key for the named value of type DWORD CUtils GetBMIHeader(const AM_MEDIA_TYPE* pamt) 静止画保存 説明:Returns the BITMAPINFOHEADER structure from media type format extension GetBMIHeader(const CMediaType mt) 静止画保存 説明:Returns the BITMAPINFOHEADER structure from media type format extension GetAvgTimePerFrame(const AM_MEDIA_TYPE* pamt) 平均FPS取得 説明:Returns the average time per frame from media type format extension GetImageSize(BITMAPINFOHEADER* pbmih) サイズ取得 説明:Calculates the image size FPS定義(?) UNITS = 10 ^ 7 UNITS / 30 = 30 fps; UNITS / 20 = 20 fps, etc const REFERENCE_TIME FPS_30 = UNITS / 30; const REFERENCE_TIME FPS_2997 = UNITS * 1001 / 30000; const REFERENCE_TIME FPS_25 = UNITS / 25; const REFERENCE_TIME FPS_24 = UNITS / 24; const REFERENCE_TIME FPS_23976 = UNITS * 1001 / 24000; const REFERENCE_TIME FPS_20 = UNITS / 20; const REFERENCE_TIME FPS_10 = UNITS / 10; const REFERENCE_TIME FPS_5 = UNITS / 5; const REFERENCE_TIME FPS_4 = UNITS / 4; const REFERENCE_TIME FPS_3 = UNITS / 3; const REFERENCE_TIME FPS_2 = UNITS / 2; const REFERENCE_TIME FPS_1 = UNITS / 1; クラス(DecklinkCapture.h) CDecklinkCaptureApp CDecklinkCaptureApp() 説明:CDecklinkCaptureApp construction InitInstance() 説明:CDecklinkCaptureApp initialization サンプル http //www13.atwiki.jp/bmd_intensity?cmd=upload act=open pageid=17 file=SDK.zip